home *** CD-ROM | disk | FTP | other *** search
/ The 640 MEG Shareware Studio 2 / The 640 Meg Shareware Studio CD-ROM Volume II (Data Express)(1993).ISO / clang / jcool01.zip / TEST_HAN.C < prev    next >
C/C++ Source or Header  |  1992-10-01  |  8KB  |  258 lines

  1. //
  2. // Copyright (C) 1991 General Electric Company.
  3. //
  4. // Permission is granted to any individual or institution to use, copy, modify,
  5. // and distribute this software, provided that this complete copyright and
  6. // permission notice is maintained, intact, in all copies and supporting
  7. // documentation.
  8. //
  9. // General Electric Company provides this software "as is" without
  10. // express or implied warranty.
  11. //
  12. // Updated: JAM 08/19/92 -- modernized template syntax, remove macro hacks
  13.  
  14. #include <cool/Vector.h>
  15. #include <cool/Vector.C>
  16.  
  17. template <class Type>
  18. class CoolSharedVector : public CoolVector<Type>, public CoolShared {
  19. public:
  20.   CoolSharedVector() : CoolVector<Type>() {}
  21.   CoolSharedVector(size_t n) : CoolVector<Type>(n) {}
  22.   CoolSharedVector(void* p, size_t n) : CoolVector<Type>(p,n) {}
  23.   CoolSharedVector(size_t n, const Type& t) : CoolVector<Type>(n,t) {}
  24.   // did not do CoolVector(size_t n, size_t num_init, const T&, ...)
  25. };
  26.  
  27. #include <cool/Handle.h>
  28. #include <test.h>
  29.  
  30.  
  31. void test_constructor () {            // test constructors
  32.   typedef CoolSharedVector<int> SharedVec;
  33.   CoolHandle< SharedVec > h0;
  34. //  CoolHandle< CoolSharedVector<int> > h0;
  35.   TEST ("Handle h0", ptr(h0), NULL);        // empty handle
  36.  
  37.   CoolSharedVector<int>* v0 = new CoolSharedVector<int>();
  38.   TEST ("Type* ptr", v0->reference_count(), 0); // count initially 0
  39.  
  40.   CoolHandle<CoolSharedVector<int> > h1(v0);        // construct from ptr
  41.   TEST ("Handle h1(Type*)", h1->reference_count(), 1); 
  42.   {
  43.     CoolHandle<CoolSharedVector<int> > h2(*v0);    // construct from obj
  44.     TEST ("Handle h2(Type&)", v0->reference_count(), 2);
  45.     {
  46.       CoolHandle<CoolSharedVector<int> > h3(h1);    // copy constructor
  47.       TEST ("Handle h3(Handle&)", v0->reference_count(), 3);
  48.     }
  49.     TEST ("~Handle", v0->reference_count(), 2);
  50.   }
  51.   TEST ("~Handle", v0->reference_count(), 1);
  52. }
  53.  
  54. void test_assign () {                // test assignment operators.
  55.   CoolSharedVector<int>* v0 = new CoolSharedVector<int>();
  56.   TEST ("Type* ptr", v0->reference_count(), 0); // count initially 0
  57.   
  58.   CoolHandle<CoolSharedVector<int> > h1 = v0;        // assign ptr
  59.   TEST ("Handle h1 = Type*", v0->reference_count(), 1);
  60.   {
  61.     CoolHandle<CoolSharedVector<int> > h2 = *v0;    // assign obj
  62.     TEST ("Handle h2 = Type&", v0->reference_count(), 2);
  63.     {
  64.       CoolHandle<CoolSharedVector<int> > h3 = h1;    // assign hdl
  65.       TEST ("Handle h3 = Handle&", v0->reference_count(), 3);
  66.     }
  67.     TEST ("~Handle", v0->reference_count(), 2);
  68.   }
  69.   TEST ("~Handle", v0->reference_count(), 1);
  70. }
  71.  
  72.  
  73. void test_conversion_deref () {        // test conversion and ->
  74.   CoolSharedVector<int>* v0 = new CoolSharedVector<int>();
  75.   CoolHandle<CoolSharedVector<int> > h1(v0);
  76.   TEST ("Handle h(Type*)", h1->reference_count(), 1); // operator ->
  77.   
  78.   CoolSharedVector<int>* v1 = ptr(h1);        // manually convert to ptr
  79.   TEST ("ptr(Handle&)", v1, v0);
  80.   
  81.   CoolSharedVector<int>& v11 = ref(h1);        // manually convert to ref
  82.   TEST ("ref(Handle&)", &v11, v0);
  83.   
  84.   {
  85.     CoolHandle<CoolSharedVector<int> > h2;
  86.     {
  87.       h2 = hdl(v0);                // manually convert to hdl
  88.     }                        // make 2 handles (stack & value)
  89.     TEST ("hdl(Type*)", h2->reference_count(), 2); // tmp hdl deleted 
  90.     
  91.     CoolSharedVector<int>* v2 = h2;            // automatic conversion to ptr
  92.     TEST ("(Type*) h", v2, v1);
  93.   }
  94.   TEST ("~Handle", h1->reference_count(), 1);
  95. }
  96.  
  97.  
  98. void test_bind_cmp () {            // test bind and compare ops
  99.   CoolSharedVector<int>* v0 = new CoolSharedVector<int>();
  100.   CoolHandle<CoolSharedVector<int> > h1(v0);
  101.   TEST ("Handle h(Type*)", v0->reference_count(), 1); 
  102.   
  103.   CoolHandle<CoolSharedVector<int> > h2;
  104.   h2 = v0;
  105.   TEST ("h2 = v0", v0->reference_count(), 2);   
  106.   
  107.   h1 = v0;
  108.   TEST ("h1 = v0", v0->reference_count(), 2);   
  109.   
  110.   TEST ("h1 == h2", h1 == h2, 1);
  111.   
  112.   h2 = new CoolSharedVector<int>();
  113.   TEST ("h1 != h2", h1 != h2, 1);  
  114. }
  115.  
  116. void test_use () {                // example of use and style
  117.   typedef CoolSharedVector<int> Object;
  118.   typedef CoolHandle<CoolSharedVector<int> > ObjectH;
  119.   typedef CoolSharedVector<int>* ObjectP;
  120.   typedef CoolSharedVector<int>& ObjectR;
  121.   typedef CoolSharedVector<CoolHandle<CoolSharedVector<int> > > Container;
  122.   
  123.   ObjectH h = hdl(new Object(1, 1));        // smart compilers reuse temp hdl
  124.   TEST ("ObjectH h = hdl(p)", 
  125.     (h->reference_count()==1 || h->reference_count()==2), TRUE);
  126.   
  127.   ObjectP p = new Object(1, 1);
  128.   TEST ("ObjectP p", p->reference_count(), 0);
  129.   
  130.   Container c(5, hdl(new Object()));        // temp from hdl() is deleted only
  131.   TEST ("Container c", c[0]->reference_count(), 5+1); // if scope is exited
  132.   
  133.   {
  134.     c[0] = hdl(p);                
  135.     c[1] = p;
  136.     c[2] = *p;
  137.   }
  138.   TEST ("c[i] = p", p->reference_count()==3 && c[3]->reference_count()==3, 
  139.     TRUE);
  140.   
  141.   {
  142.     ObjectH h0 = c[0];
  143.     TEST ("ObjectH h = [ci]", p->reference_count(), 4);
  144.   }
  145.   TEST ("~ObjectH", p->reference_count(), 3);
  146.   
  147.   ObjectP p0 = c[0];
  148.   TEST ("ObjectP p = [ci]", p->reference_count(), 3);
  149.   
  150.   ObjectR r0 = c[0];
  151.   TEST ("ObjectR r = [ci]", p->reference_count(), 3);
  152. }
  153.  
  154.  
  155. // handle<obj> must follow obj declaration, to access handle_count.
  156. // Ordering of class declarations should be enforced in header files.
  157.  
  158. // Children are shared between 2 parents, through handle and handle_count.
  159. // If one parent died, the count on the children are deleted. 
  160. // If all parents died, the children are also deleted.
  161. // Backward pointers from children to parents are implemented with plain pointers,
  162. // and do not use handle_count.
  163.  
  164. class Parent;                    // forward declaration.
  165.  
  166. class Child                    // child with 2 parents.
  167. : public CoolSharedVector<Parent*> {    
  168. //##friend class CoolHandle<Child>;            // for handle use
  169.  
  170. public:
  171.   Child ()
  172.     : CoolSharedVector<Parent*>() {;}
  173.   Child (Parent* p1, Parent* p2)
  174.     : CoolSharedVector<Parent*>(2) { put(p1,0); put(p2,1); }
  175.   ~Child() {;}
  176. };
  177.  
  178. typedef CoolHandle<Child> ChildH;    // used to be done by Handle
  179.  
  180. class Parent                    // parent with 2 children.
  181. : public CoolSharedVector<CoolHandle<Child> > {
  182. //##friend class CoolHandle<Parent>;        // for handle use
  183.  
  184. public:
  185.   Parent ()
  186.     : CoolSharedVector<CoolHandle<Child> >() {;}
  187.   Parent (ChildH& c1, ChildH& c2)
  188.     : CoolSharedVector<CoolHandle<Child> >(2, hdl(new Child()))
  189.       { 
  190.     put(c1,0);
  191.     put(c2,1);
  192.       }
  193.   // the following code doesnot work because of va_arg is macro
  194.   // and cannot pass objects in ... by reference. 
  195.   // Compiler doesnot have typeinfo in ... to call constructors...
  196.   //: (2, 2, c1, c2)                    
  197.  
  198.   ~Parent() {;}
  199. };
  200.  
  201.  
  202. void test_cycle () {                // test deletion of cycles
  203.   ChildH c1(new Child(NULL, NULL));
  204.   ChildH c2(new Child(NULL, NULL));
  205.   TEST ("ChildH c1", c1->reference_count(), 1);
  206.   TEST ("ChildH c2", c2->reference_count(), 1);
  207.  
  208.   {
  209.     Parent p1(c1, c2);
  210.     ref(c1)[0] = &p1;
  211.     ref(c2)[0] = &p1;
  212.     TEST ("Parent p1(c1, c2)", c1->reference_count(), 2);
  213.     TEST ("Parent p1(c1, c2)", c2->reference_count(), 2);
  214.     TEST ("Parent p1(c1, c2)", p1.reference_count(), 0);
  215.  
  216.     {
  217.       Parent p2(c1, c2);
  218.       ref(c1)[1] = &p2;
  219.       ref(c2)[1] = &p2;    
  220.       TEST ("Parent p2(c1, c2)", c1->reference_count(), 3);
  221.       TEST ("Parent p2(c1, c2)", c2->reference_count(), 3);
  222.       TEST ("Parent p2(c1, c2)", p2.reference_count(), 0);
  223.     }
  224.     TEST ("~Parent(c1)", c1->reference_count(), 2);
  225.     TEST ("~Parent(c2)", c2->reference_count(), 2);
  226.     TEST ("~Parent", p1.reference_count(), 0);
  227.   }
  228.   TEST ("~Parent(c1)", c1->reference_count(), 1);
  229.   TEST ("~Parent(c2)", c2->reference_count(), 1);
  230. }
  231.  
  232.  
  233. void test_leak () {                // test memory leak.
  234.   for (;;) {                    // use top4.1 to watch memory usage
  235.     test_constructor();
  236.     test_assign();
  237.     test_conversion_deref();
  238.     test_bind_cmp();
  239.     test_use();
  240.     test_cycle();
  241.   }
  242. }
  243.  
  244. int main (void) {
  245.   START("CoolHandle");
  246.   test_constructor();
  247.   test_assign();
  248.   test_conversion_deref();
  249.   test_bind_cmp();
  250.   test_use();
  251.   test_cycle();
  252. #if LEAK
  253.   test_leak();
  254. #endif
  255.   SUMMARY();
  256.   return 0;
  257. }
  258.